package com.huarun.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.filter.DelegatingFilterProxy;

/**
 * @author hqy
 * @创建时间   2018-10-18 10:17
 * @Description 访问过滤设置
 */
@Configuration
public class ShiroConfig {
	/**
	 * 安全管理器
	 * @param realm
	 * @return
	 */
	@Bean
	public DefaultWebSecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(shiroRealm());
		securityManager.setSessionManager(sessionManager());
		return securityManager;
	}

	/**
	 * Realm配置
	 * @return
	 */
	public ShiroRealm shiroRealm() {
		return new ShiroRealm();
	}

	/**
	 * SessionDAO配置
	 * @return
	 */
	@Bean
	public SessionDAO sessionDAO() {
		return new MemorySessionDAO();
	}

	/**
	 * sessionManager配置
	 * @param sessionDAO
	 * @return
	 */
	@Bean
	public DefaultWebSessionManager sessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setSessionDAO(sessionDAO());
		return sessionManager;
	}

	/**
	 * shiroFilter配置
	 * @param securityManager
	 * @return
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
		shiroFilter.setSecurityManager(securityManager());
		Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
//		filters.put("loginFilter", new LoginAuthorizationFilter());
		filters.put("corsFilter", new RestFilter());
		filters.put("urlValidateFilter", new UrlValidateFilter());
		filters.put("pcFilter", new PCUrlValidateFilter());
		shiroFilter.setFilters(filters);
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		//		filterChainDefinitionMap.put("/login/login", "anon,loginFilter");
		//		filterChainDefinitionMap.put("/login/logout", "anon");
		//		filterChainDefinitionMap.put("/login/unauth", "anon");
		filterChainDefinitionMap.put("/wx/**", "urlValidateFilter,corsFilter");
		filterChainDefinitionMap.put("/pc/**", "pcFilter,corsFilter");
		filterChainDefinitionMap.put("/swagger-ui.html", "anon");
		filterChainDefinitionMap.put("/static/**", "anon");// 需要下面一起设置才行
		filterChainDefinitionMap.put("/visitor.html", "anon");
		filterChainDefinitionMap.put("/videoPage.html", "anon");//智慧邮局
		filterChainDefinitionMap.put("/jquery.min.js", "anon");
		filterChainDefinitionMap.put("/base.css", "anon");
		filterChainDefinitionMap.put("/huarunlogo.png", "anon");// 访问二维码
		filterChainDefinitionMap.put("/weapp-qrcode.js", "anon");// 生成二维码js
		filterChainDefinitionMap.put("/YHJVCqqYrB.txt", "anon");// 业务域名认证
		filterChainDefinitionMap.put("/SMS/**", "anon");
		filterChainDefinitionMap.put("/login/*", "anon");//通过code 换取skey
		filterChainDefinitionMap.put("/wx/ioReadImg", "anon");//放开图片展示接口
		filterChainDefinitionMap.put("/wx/toilet/*", "anon");//厕所接口
//		filterChainDefinitionMap.put("/login/loginWelink", "anon");//暂时放开给微瓴地图用的
		filterChainDefinitionMap.put("/swagger-resources", "anon");
		filterChainDefinitionMap.put("/swagger-resources/configuration/security", "anon");
		filterChainDefinitionMap.put("/swagger-resources/configuration/ui", "anon");
		filterChainDefinitionMap.put("/v2/api-docs", "anon");
		filterChainDefinitionMap.put("/webjars/**", "anon");
		filterChainDefinitionMap.put("/**", "authc");
		shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
		
		//shiroFilter.setLoginUrl("/login/unauth");
		return shiroFilter;
	}

	/**
	 * 保证实现了Shiro内部lifecycle函数的bean执行
	 */
	@Bean
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	/**
	 * 启用shrio授权注解拦截方式，AOP式方法级权限检查
	 */
	@Bean
	@DependsOn(value = "lifecycleBeanPostProcessor") //依赖其他bean的初始化
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		return new DefaultAdvisorAutoProxyCreator();
	}

	/**
	 * 加入注解的使用，不加入这个注解不生效 使用shiro框架提供的切面类，用于创建代理对象 
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
			DefaultWebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Bean
	public FilterRegistrationBean delegatingFilterProxy() {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
		DelegatingFilterProxy proxy = new DelegatingFilterProxy();
		proxy.setTargetFilterLifecycle(true);
		proxy.setTargetBeanName("shiroFilter");
		filterRegistrationBean.setFilter(proxy);
		return filterRegistrationBean;
	}

	@Bean("shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean() {
		ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
		return filterFactoryBean;
	}
}
